home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
176-200
/
disk_190
/
nethack
/
twee.zoo
/
monmove.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-07-24
|
11KB
|
461 lines
/* SCCS Id: @(#)monmove.c 2.3 87/12/12
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
#include "hack.h"
#include "mfndpos.h"
#define NULL (char *) 0
extern struct obj *mksobj_at();
extern int warnlevel; /* defined in mon.c */
dochugw(mtmp) register struct monst *mtmp; {
register x = mtmp->mx;
register y = mtmp->my;
register d = dochug(mtmp);
register dd;
if(!d) /* monster still alive */
if(Warning)
if(!mtmp->mpeaceful)
if(mtmp->data->mlevel > warnlevel)
if((dd = dist(mtmp->mx,mtmp->my)) < dist(x,y))
if(dd < 100)
if(!canseemon(mtmp))
warnlevel = mtmp->data->mlevel;
return(d);
}
/* returns 1 if monster died moving, 0 otherwise */
dochug(mtmp)
register struct monst *mtmp;
{
register struct permonst *mdat;
register tmp, nearby, scared, onscary;
if(mtmp->cham && !rn2(6))
(void) newcham(mtmp,
#ifndef RPH
&mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
#else
(struct permonst *)0);
#endif
mdat = mtmp->data;
if(mdat->mlevel < 0)
panic("bad monster %c (%d)",mdat->mlet,mdat->mlevel);
/* regenerate monsters */
if((!(moves%20) || index(MREGEN, mdat->mlet)) &&
mtmp->mhp < mtmp->mhpmax)
mtmp->mhp++;
if(mtmp->mfroz) {
if (Hallucination) pmon(mtmp);
return(0); /* frozen monsters don't do anything */
}
if(mtmp->msleep) /* there is a chance we will wake it */
if(!disturb(mtmp)) return(0);
/* not frozen or sleeping: wipe out texts written in the dust */
wipe_engr_at(mtmp->mx, mtmp->my, 1);
/* confused monsters get unconfused with small probability */
if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0;
/* some monsters teleport */
if(mtmp->mflee && index("tNL", mdat->mlet) && !rn2(40)){
rloc(mtmp);
return(0);
}
if(mdat->mmove < rnd(6)) return(0);
/* fleeing monsters might regain courage */
if(mtmp->mflee && !mtmp->mfleetim
&& mtmp->mhp == mtmp->mhpmax && !rn2(25))
mtmp->mflee = 0;
nearby = (dist(mtmp->mx, mtmp->my) < 3);
onscary = (sengr_at("Elbereth", u.ux, u.uy) ||
sobj_at(SCR_SCARE_MONSTER, u.ux, u.uy));
scared = (nearby && onscary && !mtmp->mtame && mtmp->mcansee)
&& (mdat->mlet != '1'); /* RPH: the wiz is never scared */
if(scared && !mtmp->mflee) {
mtmp->mflee = 1;
mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
}
if(!nearby ||
mtmp->mflee || scared ||
mtmp->mconf ||
(mtmp->minvis && !rn2(3)) ||
#ifndef KOPS
(index("BIuy", mdat->mlet) && !rn2(4)) ||
#else
(index("KBIuy", mdat->mlet) && !rn2(4)) ||
#endif
(mdat->mlet == 'L' && !u.ugold && (mtmp->mgold || rn2(2))) ||
(!mtmp->mcansee && !rn2(4)) ||
mtmp->mpeaceful
) {
tmp = m_move(mtmp,0); /* 2: monster died moving */
if(tmp == 2 || (tmp && mdat->mmove <= 12))
return(tmp == 2);
if(Hallucination && tmp==0) pmon(mtmp);
/* If 0, this means the monster didn't move. During hallucination, its
appearance should still change. */
#ifdef HARD
/* Without this line, fast monsters don't hit you when they've
* caught up to you. -dgk
*/
nearby = (dist(mtmp->mx, mtmp->my) < 3);
scared = (nearby && onscary);
if(scared && !mtmp->mflee) {
mtmp->mflee = 1;
mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
}
#endif
}
#ifdef HARD /* Demonic Blackmail!!! */
if(mdat->mlet == '&' && mtmp->mpeaceful
&& !mtmp->mtame && !mtmp->isdjinni)
if(demon_talk(mtmp))
return(1); /* you paid it off */
#endif
if(!index("Ea", mdat->mlet) && nearby &&
!mtmp->mpeaceful && u.uhp > 0 && !scared) {
if(mhitu(mtmp))
return(1); /* monster died (e.g. 'y' or 'F') */
}
/* extra movement for fast monsters */
if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp,1);
return(tmp == 2);
}
m_move(mtmp,after)
register struct monst *mtmp;
{
#ifndef REGBUG
register
#endif
struct monst *mtmp2;
#ifndef REGBUG
register
#endif
int nx,ny,omx,omy,appr,nearer,cnt,i,j;
xchar gx,gy,nix,niy,chcnt;
schar chi;
boolean likegold, likegems, likeobjs;
#ifdef KAA
boolean likerock;
#endif
char msym = mtmp->data->mlet;
schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */
coord poss[9];
long info[9];
if(mtmp->mfroz || mtmp->msleep)
return(0);
if(mtmp->mtrapped) {
i = mintrap(mtmp);
if(i == 2) return(2); /* he died */
if(i == 1) return(0); /* still in trap, so didnt move */
}
if(mtmp->mhide && o_at(mtmp->mx,mtmp->my) && rn2(10))
return(0); /* do not leave hiding place */
#ifndef NOWORM
if(mtmp->wormno)
goto not_special;
#endif
/* my dog gets a special treatment */
if(mtmp->mtame) {
return( dog_move(mtmp, after) );
}
/* likewise for shopkeeper */
if(mtmp->isshk) {
mmoved = shk_move(mtmp);
if(mmoved >= 0)
goto postmov;
mmoved = 0; /* follow player outside shop */
}
/* and for the guard */
if(mtmp->isgd) {
mmoved = gd_move();
goto postmov;
}
/* teleport if that lies in our nature ('t') or when badly wounded ('1') */
if((msym == 't' && !rn2(5))
|| (msym == '1' && (mtmp->mhp < 7 || (!xdnstair && !rn2(5))
|| RM_TYP(levl[u.ux][u.uy]) == STAIRS))) {
if(mtmp->mhp < 7 || (msym == 't' && rn2(2)))
rloc(mtmp);
else
mnexto(mtmp);
mmoved = 1;
goto postmov;
}
/* spit fire ('D') or use a wand ('1') when appropriate */
#ifdef DGKMOD
/* Add arrow and bolt throwing monsters */
if (index(
# ifdef KAA
# ifdef KOPS
"D1OKC9",
# else
"D1KC9",
# endif
# else
# ifdef KOPS
"D1OKC",
# else
"D1KC",
# endif
# endif
msym))
if (!inrange(mtmp)) /* inrange returns 1 if OK for mon */
return(0); /* to move after it zaps or throws */
#else
if(index("D1", msym))
inrange(mtmp);
#endif
if(msym == 'U' && !mtmp->mcan && canseemon(mtmp) &&
mtmp->mcansee && rn2(5)) {
if(!Confusion)
pline("%s's gaze has confused you!", Monnam(mtmp));
else
pline("You are getting more and more confused.");
if(rn2(3)) mtmp->mcan = 1;
HConfusion += d(3,4); /* timeout */
}
#ifdef RPH
if (msym == '8' && canseemon(mtmp)) {
if (mtmp->mcan)
pline ("You notice that %s isn't all that ugly.",monnam(mtmp));
else if (rn2(3))
pline ("You see the ugly back of %s.", monnam(mtmp));
else {
pline ("You look upon %s.", monnam(mtmp));
pline ("You turn to stone.");
done_in_by(mtmp);
}
}
#endif
not_special:
if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1);
appr = 1;
if(mtmp->mflee) appr = -1;
if(mtmp->mconf || Invis || !mtmp->mcansee ||
(index("BIy", msym) && !rn2(3)))
appr = 0;
omx = mtmp->mx;
omy = mtmp->my;
gx = u.ux;
gy = u.uy;
if(msym == 'L' && appr == 1 && mtmp->mgold > u.ugold)
appr = -1;
/* random criterion for 'smell' or track finding ability
should use mtmp->msmell or sth
*/
if(msym == '@' ||
#ifdef RPH
uwep && !strcmp(ONAME(uwep), "Excalibur") ||
#endif
('a' <= msym && msym <= 'z')) {
extern coord *gettrack();
register coord *cp;
schar mroom;
mroom = inroom(omx,omy);
if(mroom < 0 || mroom != inroom(u.ux,u.uy)){
cp = gettrack(omx,omy);
if(cp){
gx = cp->x;
gy = cp->y;
}
}
}
/* look for gold or jewels nearby */
#ifdef ROCKMOLE
likegold = (index("LODr", msym) != NULL);
likegems = (index("ODu", msym) != NULL);
# ifdef KJSMODS
likeobjs = (mtmp->mhide || (msym == 'r' && dlevel > 3));
# else
likeobjs = (mtmp->mhide || msym == 'r');
# endif
#else
likegold = (index("LOD", msym) != NULL);
likegems = (index("ODu", msym) != NULL);
likeobjs = mtmp->mhide;
#endif
#ifdef KAA
likerock = (msym == '9');
#endif
#define SRCHRADIUS 25
{ xchar mind = SRCHRADIUS; /* not too far away */
register int dd;
if(likegold){
register struct gold *gold;
for(gold = fgold; gold; gold = gold->ngold)
if((dd = DIST(omx,omy,gold->gx,gold->gy)) < mind){
mind = dd;
gx = gold->gx;
gy = gold->gy;
}
}
if(likegems || likeobjs
#ifdef KAA
|| likerock
#endif
) {
register struct obj *otmp;
for(otmp = fobj; otmp; otmp = otmp->nobj)
if(likeobjs
|| (likegems && otmp->olet == GEM_SYM)
#ifdef KAA
|| (likerock && otmp->olet == ROCK_SYM)
#endif
) {
if(msym != 'u' || objects[otmp->otyp].g_val != 0)
if((dd = DIST(omx,omy,otmp->ox,otmp->oy)) < mind){
mind = dd;
gx = otmp->ox;
gy = otmp->oy;
}
}
}
if(mind < SRCHRADIUS && appr == -1) {
if(dist(omx,omy) < 10) {
gx = u.ux;
gy = u.uy;
} else
appr = 1;
}
}
nix = omx;
niy = omy;
cnt = mfndpos(mtmp,poss,info,
msym == 'u' ? NOTONL :
#ifdef ROCKMOLE
# ifdef KJSMODS
(msym == 'r' && dlevel > 3) ? ALLOW_WALL :
# else
msym == 'r' ? ALLOW_WALL :
# endif
#endif
(msym == '@' || msym == '1') ? (ALLOW_SSM | ALLOW_TRAPS) :
index(UNDEAD, msym) ? NOGARLIC :
#ifdef KAA
(msym == '9') ? (ALLOW_ROCK | ALLOW_TRAPS) : ALLOW_TRAPS);
#else
ALLOW_TRAPS);
#endif
chcnt = 0;
chi = -1;
for(i=0; i<cnt; i++) {
nx = poss[i].x;
ny = poss[i].y;
for(j=0; j<MTSZ && j<cnt-1; j++)
if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
if(rn2(4*(cnt-j))) goto nxti;
#ifdef STUPID
/* some stupid compilers think that this is too complicated */
{ int d1 = DIST(nx,ny,gx,gy);
int d2 = DIST(nix,niy,gx,gy);
nearer = (d1 < d2);
}
#else
nearer = (DIST(nx,ny,gx,gy) < DIST(nix,niy,gx,gy));
#endif
if((appr == 1 && nearer) || (appr == -1 && !nearer) ||
!mmoved ||
(!appr && !rn2(++chcnt))){
nix = nx;
niy = ny;
chi = i;
mmoved = 1;
}
nxti: ;
}
if(mmoved){
if(info[chi] & ALLOW_M){
mtmp2 = m_at(nix,niy);
if(hitmm(mtmp,mtmp2) == 1 && rn2(4) &&
hitmm(mtmp2,mtmp) == 2) return(2);
return(0);
}
if(info[chi] & ALLOW_U){
(void) hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd)+1);
return(0);
}
mtmp->mx = nix;
mtmp->my = niy;
for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1];
mtmp->mtrack[0].x = omx;
mtmp->mtrack[0].y = omy;
#ifndef NOWORM
if(mtmp->wormno) worm_move(mtmp);
#endif
} else {
if(msym == 'u' && rn2(2)){
rloc(mtmp);
return(0);
}
#ifndef NOWORM
if(mtmp->wormno) worm_nomove(mtmp);
#endif
}
postmov:
if(mmoved == 1) {
if(mintrap(mtmp) == 2) /* he died */
return(2);
#ifdef ROCKMOLE
/* Maybe a rock mole just ate something? */
if(msym == 'r'
# ifdef KJSMODS
&& dlevel > 3
#endif
&& IS_ROCK(RM_TYP(levl[mtmp->mx][mtmp->my])) &&
RM_TYP(levl[mtmp->mx][mtmp->my]) != POOL){
register int pile = rnd(25);
/* Just ate something. */
if (RM_TYP(levl[mtmp->mx][mtmp->my]) == 0)
RM_SET_TYP(levl[mtmp->mx][mtmp->my], CORR);
else if (IS_WALL(RM_TYP(levl[mtmp->mx][mtmp->my])))
RM_SET_TYP(levl[mtmp->mx][mtmp->my], DOOR);
mnewsym(mtmp->mx,mtmp->my);
/* Left behind a pile? */
if(pile < 5) {
if(pile == 1)
mksobj_at(ENORMOUS_ROCK, mtmp->mx, mtmp->my);
else
mksobj_at(ROCK, mtmp->mx, mtmp->my);
}
if(cansee(mtmp->mx, mtmp->my))
if(fobj) atl(mtmp->mx,mtmp->my,fobj->olet);
}
/* Maybe a rock mole just ate some gold or armor? */
if(msym == 'r') meatgold(mtmp);
#endif /* ROCKMOLE /**/
if(likegold) mpickgold(mtmp);
#ifdef KAA
if(likerock || likegems) mpickgems(mtmp);
#else
if(likegems) mpickgems(mtmp);
#endif
if(mtmp->mhide) mtmp->mundetected = 1;
}
pmon(mtmp);
return(mmoved);
}